﻿/*
 * UserPersistenceHandler.cs
 * 
 * Purpose:
 * Handles serializing and deserializing User objects for persistence.
 * 
 * Revision Log:
 * 08-SEP-12, C. Bush, First Draft.
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;

using Air_Trafic_Control.Domain.Entity;

namespace Air_Trafic_Control.Domain.Persistence
{
    public class UserPersistenceHandler
    {
        private List<User> users = new List<User>();
        private string directory = "";


        /// <summary>
        /// Scan the directory for the UserList.uph file to get a list of users that should be in the directory. Add the ones found to the list of users.
        /// </summary>
        /// <param name="directory">The directory for persistent storage being used.</param>
        public UserPersistenceHandler(string directory)
        {
            List<string> userNames = new List<string>();
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(User));
            TextReader textReader = null;

            // Set the directory
            this.directory = directory;

            try
            {
                // If the file does not exist, create it
                if (!(File.Exists(directory + "\\UserList.uph")))
                {
                    File.Create(directory + "\\UserList.uph").Close();
                }
            }
            catch (Exception e)
            {
                System.Console.WriteLine("[UserPersistenceHandler.UserPersistenceHandler] Exception encountered while creating new UserList.uph file.");
                System.Console.WriteLine(e.Message);
            }

            try
            {
                // Read the lines of the file -- each line has a user name on it
                foreach (string nextLine in File.ReadLines(directory + "\\UserList.uph"))
                {
                    userNames.Add(nextLine);
                }
            }
            catch (Exception e)
            {
                System.Console.WriteLine("[UserPersistenceHandler.UserPersistenceHandler] Exception encountered while reading lines from UserList.uph file.");
                System.Console.WriteLine(e.Message);
            }

            try
            {
                // Get each file and deserialize the User object from it
                foreach (string userName in userNames)
                {
                    textReader = new StreamReader(File.Open(directory + "\\" + userName + ".user", FileMode.Open, FileAccess.Read));

                    this.users.Add((User)xmlSerializer.Deserialize(textReader));

                    textReader.Close();
                }
            }
            catch (Exception e)
            {
                System.Console.WriteLine("[UserPersistenceHandler.UserPersistenceHandler] Exception encountered while deserializing user files.");
                System.Console.WriteLine(e.Message);
            }
        }

        /// <summary>
        /// Accessor for users list.
        /// </summary>
        public List<User> Users
        {
            get
            {
                return this.users;
            }
        }

        /// <summary>
        /// Add a new user to the list. If the user already exists, false is returned. True is returned otherwise.
        /// </summary>
        /// <param name="user">(User) The new user to be added.</param>
        /// <returns>(bool) True if the user does not already exist and is added. False, otherwise.</returns>
        public bool AddUser(User user)
        {
            foreach (User u in this.users)
            {
                if (u.Name.Equals(user.Name))
                {
                    return false;
                }
            }

            this.users.Add(user);
            return true;
        }

        /// <summary>
        /// Remove a user.
        /// </summary>
        /// <param name="userName">The name of the user to be removed.</param>
        /// <returns>True if the user is found and removed. False, otherwise.</returns>
        public bool RemoveUser(string userName)
        {
            User userToRemove = null;
            foreach (User u in this.users)
            {
                if (u.Name.Equals(userName))
                {
                    userToRemove = u;
                    break;
                }
            }

            if (userToRemove != null)
            {
                this.users.Remove(userToRemove);
                return true;
            }

            return false;
        }
        
        /// <summary>
        /// Updates the user list file and then serializes all the users to their own files.
        /// </summary>
        /// <returns>True if the operation is successful.</returns>
        public bool SaveUsers()
        {
            List<string> userNames = new List<string>();
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(User));
            TextWriter textWriter = null;

            try
            {
                // Update the UserList.uph file with the current list of names. Replace spaces with underscores.
                textWriter = new StreamWriter(File.Open(this.directory + "\\UserList.uph", FileMode.Create, FileAccess.Write));

                foreach (User u in this.users)
                {
                    textWriter.WriteLine(u.Name.Replace(' ', '_'));
                }

                textWriter.Close();
            }
            catch (Exception e)
            {
                System.Console.WriteLine("[UserPersistenceHandler.SaveUsers] Exception encountered while writing user list to UserList.uph.");
                System.Console.WriteLine(e.Message);

                return false;
            }

            // Now, let's serialize all the users to their own files.
            foreach (User u in this.users)
            {
                try
                {
                    textWriter = new StreamWriter(File.Open(this.directory + "\\" + u.Name.Replace(' ', '_') + ".user", FileMode.Create, FileAccess.Write));

                    xmlSerializer.Serialize(textWriter, u);

                    textWriter.Close();
                }
                catch (Exception e)
                {
                    System.Console.WriteLine("[UserPersistenceHandler.SaveUsers] Exception encountered while serializing users to persistence.");
                    System.Console.WriteLine(e.Message);
                    return false;
                }
            }

            return true;
        }
        
    }
}
